package com.css.apps.base.org.action;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.css.apps.base.org.model.SOrg;
import com.css.core.configuration.Environment;
import com.css.core.model.tree.Tree;
import com.css.core.model.tree.TreeCache;
import com.css.core.model.tree.TreeNode;
import com.css.db.query.QueryCache;
import com.css.db.query.TransactionCache;
import com.css.util.Ajax;
import com.css.util.Messages;
import com.css.util.StringHelper;
import com.css.webbase.webwork.action.AdminAction;
import com.opensymphony.xwork.Action;

@SuppressWarnings("serial")
public class DragOrgTree extends AdminAction {
	private static Log log = LogFactory.getLog(DragOrgTree.class);
	private String targetId; // 如果modeType为inner,targetId为新的parentId;如果modeType为prev或者next,targetId为兄弟节点
	private String moveType;
	private String nodeIds;

	private void updOrgTree(String parentId, List<?> nodeIds) {
		for (int i = 0; i < nodeIds.size(); i++) {
			Object node = nodeIds.get(i);
			String nodeId = "";
			if (node instanceof SOrg) {
				nodeId = ((SOrg) node).getUuid();
			} else {
				nodeId = node.toString();
			}
			Tree tree = new TreeCache(SOrg.class);
			List<TreeNode> treeNodes = tree.getTree();
			for (int j = 0; j < treeNodes.size(); j++) {
				TreeNode treeNode = treeNodes.get(j);
				if (nodeId.equals(treeNode.getNodeId())) {
					treeNode.removeChild(treeNode);
				}
			}
			TreeNode parentNode = tree.getTreeNode(parentId);
			TreeNode newNode = new TreeNode();
			newNode.setNodeId(nodeId);
			newNode.setParentId(parentId.trim());
			parentNode.addChild(newNode);
			tree.refresh(sUser.getUserId());
		}
	}

	private List<SOrg> getOrderOrgs(String parentId, String targetId, List<String> nodeIds, String moveType) {
		if (nodeIds == null || nodeIds.size() == 0) {
			return null;
		}
		Tree tree = new TreeCache(SOrg.class);
		List<TreeNode> brotherNodes = tree.getTreeNode(parentId).getChildren(); // 获得所有兄弟节点
		List<String> brotherIds = new ArrayList<String>();
		if (brotherNodes != null) {
			for (TreeNode node : brotherNodes) {
				brotherIds.add(node.getNodeId());
			}
		}
		brotherIds.removeAll(nodeIds);
		int targetIndex = brotherIds.indexOf(targetId);
		if ("prev".equals(moveType)) {
			if (targetIndex != -1) {
				targetIndex--;
			}
		} else if ("inner".equals(moveType)) {
			targetIndex = -1;
		}
		targetIndex++;
		for (String nodeId : nodeIds) {
			brotherIds.add(targetIndex++, nodeId);
		}
		List<SOrg> updList = new ArrayList<SOrg>();
		int orderNum = 1;
		for (String brotherId : brotherIds) {
			SOrg org = QueryCache.get(SOrg.class, brotherId);
			org.setOrderNum(orderNum++);
			org.setParentId(parentId);
			updList.add(org);
		}
		return updList;
	}

	protected String adminGo() {
		TransactionCache tx = null;
		String parentId = targetId;
		Tree tree = new TreeCache(SOrg.class);
		try {
			if (StringHelper.isEmpty(moveType) || StringHelper.isEmpty(targetId) || StringHelper.isEmpty(nodeIds)) {
				result = Ajax.JSONResult(Environment.RESULT_CODE_ERROR, Messages.getString("systemMsg.fieldEmpty"));
				return Action.ERROR;
			}
			if (moveType.equals("prev") || moveType.equals("next")) {
				parentId = tree.getTreeNode(targetId).getParentId();
			}
			List<String> listIds = StringHelper.strToList(nodeIds.trim());
			List<SOrg> orderOrgs = getOrderOrgs(parentId, targetId, listIds, moveType);
			tx = new TransactionCache();
			tx.update(orderOrgs);
			tx.commit();
			updOrgTree(parentId, orderOrgs);
			tree.refresh();
			result = Ajax.JSONResult(Environment.RESULT_CODE_SUCCESS, Messages.getString("systemMsg.success"));
			return Action.SUCCESS;
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
			if (tx != null) {
				tx.rollback();

			}
			result = Ajax.JSONResult(Environment.RESULT_CODE_ERROR, Messages.getString("systemMsg.exception"));
			return Action.ERROR;
		}
	}

	public String getTargetId() {
		return targetId;
	}

	public void setTargetId(String targetId) {
		this.targetId = targetId;
	}

	public String getMoveType() {
		return moveType;
	}

	public void setMoveType(String moveType) {
		this.moveType = moveType;
	}

	public String getNodeIds() {
		return nodeIds;
	}

	public void setNodeIds(String nodeIds) {
		this.nodeIds = nodeIds;
	}
}
